#ifndef BINARY_IO_H
#define BINARY_IO_H

#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>
#include <vector>

class BinaryIO {
public:
    template <class T>
    static T unpack(std::vector<uint8_t> data, uint32_t start,
                    bool bigEndian = true) {
        T v;
        std::memcpy(&v, data.data() + start, sizeof(v));
        v = byte_swap(v, bigEndian);
        return v;
    }
    // 从文件读取指定类型
    template <typename T>
    static T read_value(std::ifstream& file, bool bigEndian = true) {
        T value;
        file.read(reinterpret_cast<char*>(&value), sizeof(T));
        value = byte_swap(value, bigEndian);
        return value;
    }

    static bool isBigEndian() {
        uint16_t value = 0x01;  // 低位字节是 01
        // 将地址转换为 char*，检查第一个字节
        unsigned char* bytes = reinterpret_cast<unsigned char*>(&value);
        // 如果第一个字节是 0x01 (低位)，则是小端序
        return (bytes[0] != 0x01);
    }

    template <typename T>
    static T byte_swap(T value, bool bigEndian = true) {
        if (isBigEndian() == bigEndian) {
            return value;
        } else {
            // 1. 创建一个字节数组来存放 T 类型的字节
            unsigned char bytes[sizeof(T)];

            // 2. 将输入值 value 的内存内容复制到字节数组中
            std::memcpy(bytes, &value, sizeof(T));

            // 3. 反转字节数组的顺序
            std::reverse(bytes, bytes + sizeof(T));

            // 4. 将反转后的字节数组复制回 T 类型的变量
            T result;
            std::memcpy(&result, bytes, sizeof(T));
            return result;
        }
    }

    // 读取指定长度的字节
    static std::vector<uint8_t> read_bytes(std::ifstream& file, size_t length) {
        std::vector<uint8_t> buffer(length);
        file.read(reinterpret_cast<char*>(buffer.data()), length);
        return buffer;
    }

    // 跳过指定长度的字节
    static void skip_bytes(std::ifstream& file, size_t length) {
        file.seekg(length, std::ios::cur);
    }

    // 查找文件中的特定模式
    static long find_pattern(std::ifstream& file,
                             const std::vector<uint8_t>& pattern);
};

#endif  // BINARY_IO_H
